此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!
立馬下載 索取兌換碼
當部分 UI invalid 時,Compose 會盡可能只針對需要更新的部分進行 recompose。舉例來說,Compose 可能會重新執行一個 button 的 composable,而不執行該元件在 UI 樹狀結構中任何上層或下層的 composables。
每個 composable function 和 lambda 都可能會自行 recompose。下面的範例顯示了 recomposition 在 render 清單時如何略過部分元件:
/**
* Display a list of diaries the user can click with a header
*/
@Composable
fun Journal(
header: String,
diaries: List<String>,
onDiaryClick: (String) -> Unit
) {
Column {
// this will recompose when [header] changes, but not when [diaries] changes
Text(header, style = MaterialTheme.typography.h5)
Divider()
// LazyColumn is the Compose version of a RecyclerView.
// The lambda passed to items() is similar to a RecyclerView.ViewHolder.
LazyColumn {
items(diaries) { notes ->
// When an item's [notes] updates, the adapter for that item
// will recompose. This will not recompose when [header] changes
DiaryItem(notes, onDiaryClick)
}
}
}
}
/**
* Display a single diary the user can click.
*/
@Composable
private fun DiaryItem(notes: String, onClick: (String) -> Unit) {
Text(notes, Modifier.clickable(onClick = { onClick(notes) }))
}
上面這段 code 的各個 scope 都可能是 recomposition 期間唯一會執行的項目。當 header
變更時,Compose 可能會直接執行 Column
的 lambda,而不會執行它的任何的 parent。另外,在執行 Column
時,如果 diaries
沒有變更,Compose 可能會選擇略過 LazyColumn
的 items。
同樣地,執行所有 composable function 或 lambda 都不應該有任何 side-effect。當我們需要執行 side-effect 時,需透過 callback 觸發。
只要 Compose 認為 composable 的參數可能有變動,即會啟動 recomposition。Recomposition 具有「optimistic」的特性,這表示 Compose 預期在參數再次變更前可以完成 recomposition。如果參數在 recomposition 完成前就「有變動」,Compose 可能會取消這個 recomposition,並使用新的參數重新啟動 recomposition。
Recomposition 取消後,Compose 會捨棄 recomposition 中的 UI 樹狀結構。如果顯示的 UI 有任何 side-effect,即使 composition 取消,系統仍會套用 side-effect。這可能會導致 app 狀態不一致。
要確認所有 composable function 和 lambda 皆符合 idempotent、無 side-effect 的條件,以處理具有 optimistic 特性的 recomposition。
此系列文章是以我的業餘專案:Kimoji 為範例。
Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!
立馬下載 索取兌換碼
Reference: https://developer.android.com/jetpack/compose/mental-model